/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package mysgoog.brown.dragon;

import java.util.*;
import mysgoog.brown.*;
import mysgoog.brown.basicaction.*;
import mysgoog.brown.move.*;

public class DragonMgr implements Generator {

	private int boardsize = 13;

	private LinkedList<Move> movelist = new LinkedList<Move>();

	/* ===================Worms ====================================== */
	static public Worm_data[] worms = new Worm_data[Brown.maxSize];
	static public Dragon_data[] dragons = new Dragon_data[Brown.maxSize];
	static public Dragon2_data[] dragon2s = new Dragon2_data[Brown.maxSize];

	static {
		for (int i = 0; i < worms.length; ++i) {
			worms[i] = new Worm_data();
			dragons[i] = new Dragon_data();
		}
	}

	private int[] search_moves = new int[Brown.maxSize];
	private int search_res;

	/* ================== Dragon ===================================== */

	public DragonMgr() {

	}

	public void set_board(int size) { // like 13
		boardsize = size;
		Search.size = size * size;
	}

	public void clear_board() {
		for (int i = 0; i < worms.length; ++i) {
			worms[i].clear();
		}
	}

	public void play(int pos, int color) {
		/* suppose worms are already in circle in next_stone[] */
		updateWorm(pos, color);
		updateDragon(pos, color);
		// updateDragon(pos, color);
	}

	public void remove(int pos) {
		/*
		 * a worm will be removed entirely , pos may not be the origin
		 */
		// removeWormInDragon(worms[pos].origin);
		removeWorm(worms[pos].origin);
	}

	public LinkedList<Move> genMove(int color) {

		movelist.clear();
		searchMove(color);
		// threatMove(color);
		simpleOpenMove();

		// dragon
		/*
		 * siegeDragon(); attackDragon();
		 * 
		 * extendDragon(); defendDragon();
		 */
		Iterator<Move> iter = movelist.iterator();
		while (iter.hasNext()) {
			Move m = iter.next();
			if (!Brown.legal_move(Brown.I(m.pos), Brown.J(m.pos), color))
				iter.remove();
		}
		return movelist;
	}

	public void searchMove(int color) {
		int opp_color = Brown.OTHER_COLOR(color);
		int size = Brown.board_size * Brown.board_size;
		for (int i = 0; i < size; ++i) {
			if (worms[i].origin == i) {
				if (worms[i].color == color) {
					if (worms[i].libn <= 3) {
						Lib.log("beg1");
						search_res = Search.Defend(i, search_moves);
						for (int j = 0; j < search_res; ++j) {
							movelist.add(new Move(search_moves[j],
									Evaluator.DEFEND_MOVE, worms[i].size));
						}
						Lib.log("end1");
					}
				} else if (worms[i].color == opp_color) {
					if (worms[i].libn <= 3) {
						Lib.log("beg2");
						search_res = Search.Capture(i, search_moves);
						Lib.log("" + search_res);
						for (int j = 0; j < search_res; ++j) {
							movelist.add(new Move(search_moves[j],
									Evaluator.ATTACK_MOVE, worms[i].size));
						}
						Lib.log("end2");
					}
				}
			}
		}
	}

	public void threatMove(int color) {
		BasActionMgr.go(color);
		Answer[] res = BasActionMgr.getPlace();
		int n = BasActionMgr.getnumber();
		for (int i = 0; i < n; ++i) {
			movelist.add(new Move(res[i].place, Evaluator.THREAT, res[i].value));
		}
	}

	public void simpleOpenMove() {
		int size = Brown.board_size * Brown.board_size;
		for (int p = 0; p < size; ++p) {
			if (Brown.board[p] == Brown.EMPTY && Brown.I(p) != 0
					&& Brown.J(p) != 0 && Brown.I(p) != Brown.board_size - 1
					&& Brown.J(p) != Brown.board_size - 1) {
				boolean empty = true;
				for (int k = 0; k < 4; ++k) {
					int ai = Brown.I(p) + Brown.deltai[k];
					int aj = Brown.J(p) + Brown.deltaj[k];
					int apos = Brown.POS(ai, aj);
					if (Brown.on_board(ai, aj)
							&& Brown.board[apos] != Brown.EMPTY) {
						empty = false;
						break;
					}
				}
				if (empty)
					movelist.add(new Move(p, Evaluator.OPEN, 1));
			}
		}
	}

	public Dragon2_data Dragon2(int pos) {
		return dragon2s[dragons[pos].id];
	}

	public Dragon_data Dragon(int d) {
		return dragons[dragon2s[d].origin];
	}

	/* ====================about worms ============================== */
	/*
	 * add one stone in the board fixed by wxa
	 */
	private void updateWorm(int newStone, int color) {
		Worm_data.addUpdate(newStone, color);
	}

	/*
	 * remove a worm in the board fixed by wxa
	 */
	private void removeWorm(int org) {
		// org is origin of the worm
		Worm_data.removeUpdate(org);
	}

	/* ====================about dragons ============================== */

	private void updateDragon(int newStone, int color) {
		// already have a worm in worms[]
		Lib.assertNotReached();
	}

	private void removeWormInDragon(int org) {
		// still have a worm in worms[]
		Lib.assertNotReached();
	}

	private void siegeDragon() {
		// stop it from extending
		Lib.assertNotReached();
	}

	private void attackDragon() {
		/*
		 * many liberties : attack using information of worms[] few liberties :
		 * attack by searching
		 */
		Lib.assertNotReached();
	}

	private void extendDragon() {
		Lib.assertNotReached();
	}

	private void defendDragon() {
		/*
		 * many liberties : defend using information of worms[] few liberties :
		 * defend by searching
		 */
		Lib.assertNotReached();
	}

}
